package com.zoe.onelink.logging.biz.evaluator;

import com.zoe.onelink.logging.biz.context.BizLogEvaluationContext;
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.context.expression.CachedExpressionEvaluator;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.common.TemplateParserContext;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2021</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2021-10-12
 */
public class BizLogExpressionEvaluator extends CachedExpressionEvaluator {

    public static final TemplateParserContext TEMPLATE_PARSER_CONTEXT = new TemplateParserContext("{", "}");

    private final Map<ExpressionKey, Expression> expressionCache = new ConcurrentHashMap<>(64);

    public String parseExpression(String conditionExpression, AnnotatedElementKey methodKey, EvaluationContext evalContext) {
        return this.getExpression(this.expressionCache, methodKey, conditionExpression).getValue(evalContext, String.class);
    }

    @Override
    protected Expression getExpression(Map<ExpressionKey, Expression> cache, AnnotatedElementKey elementKey, String expression) {

        ExpressionKey expressionKey = new ExpressionCompareKey(elementKey, expression);
        Expression expr = cache.get(expressionKey);
        if (expr == null) {
            expr = getParser().parseExpression(expression, TEMPLATE_PARSER_CONTEXT);
            cache.put(expressionKey, expr);
        }
        return expr;
    }

    public EvaluationContext createEvaluationContext(BizLogRootObject root) {
        return new BizLogEvaluationContext(root, root.getMethod(), root.getArgs(), this.getParameterNameDiscoverer(), root.getResult(), root.getErrorMsg());

    }

    public static class ExpressionCompareKey extends ExpressionKey {
        public ExpressionCompareKey(AnnotatedElementKey element, String expression) {
            super(element, expression);
        }
    }


}
